// Package safe project safe.go
package safe

//协程安全包，map操作都已经加了锁
//自带锁的map

import (
	"sync"
)

// SafeMap 自带锁的map
type SafeMap[K Key, G any] struct {
	m    map[K]*G
	lock sync.RWMutex
}

// NewLockMap 新建一个字符串的Map
func NewSafeMap[K Key, G any]() *SafeMap[K, G] {
	m := new(SafeMap[K, G])
	m.Reset()
	return m
}

// Size 获取Map的数据个数
func (m *SafeMap[K, G]) Size() int {
	m.lock.RLock()
	defer m.lock.RUnlock()
	return len(m.m)
}

// Reset Map 复位 （清空数据）
func (m *SafeMap[K, G]) Reset() {
	m.lock.Lock()
	defer m.lock.Unlock()
	m.m = map[K]*G{}
}

// Find 查找给定关键字的值
func (m *SafeMap[K, G]) Get(key K) (*G, bool) {
	m.lock.RLock()
	defer m.lock.RUnlock()
	if value, ok := m.m[key]; ok {
		return value, true
	}
	return nil, false
}

// Set 指定Map指定关键字的值
func (m *SafeMap[K, G]) Set(key K, value *G) {
	m.lock.Lock()
	defer m.lock.Unlock()
	m.m[key] = value
}

// Delete 删除Map中的一个值
func (m *SafeMap[K, G]) Delete(key K) {
	m.lock.Lock()
	defer m.lock.Unlock()
	delete(m.m, key)
}

// Delete 删除Map中的一个值
func (m *SafeMap[K, G]) Pop(key K) *G {
	m.lock.Lock()
	defer m.lock.Unlock()
	if value, ok := m.m[key]; ok {
		delete(m.m, key)
		return value
	}
	return nil
}

// Deletes 删除多个值
func (m *SafeMap[K, G]) Deletes(keys []K) {
	m.lock.Lock()
	defer m.lock.Unlock()
	for i := range keys {
		delete(m.m, keys[i])
	}
}

// Remove 删除Map中的一个值
func (m *SafeMap[K, G]) Remove(key K) {
	m.lock.Lock()
	defer m.lock.Unlock()
	delete(m.m, key)
}

// Keys 获取Map中全部的关键字列表
func (m *SafeMap[K, G]) Keys() []K {
	m.lock.RLock()
	defer m.lock.RUnlock()
	keys := make([]K, 0, len(m.m))
	for key := range m.m {
		keys = append(keys, key)
	}
	return keys
}

// Values 获取Map中全部值列表
func (m *SafeMap[K, G]) Values() []*G {
	m.lock.RLock()
	defer m.lock.RUnlock()
	vals := make([]*G, 0, len(m.m))
	for _, val := range m.m {
		vals = append(vals, val)
	}
	return vals
}

// KeyValues 获取Map中键值对列表
func (m *SafeMap[K, G]) KeyValues() (keys []K, vals []*G) {
	m.lock.RLock()
	defer m.lock.RUnlock()
	keys = make([]K, 0, len(m.m))
	vals = make([]*G, 0, len(keys))
	for key, val := range m.m {
		keys = append(keys, key)
		vals = append(vals, val)
	}
	return
}

func (m *SafeMap[K, G]) GetKVs() []*KV[K, G] {
	m.lock.RLock()
	defer m.lock.RUnlock()
	var kvs = make([]*KV[K, G], len(m.m))
	i := 0
	for key, val := range m.m {
		kvs[i] = &KV[K, G]{K: key, V: val}
		i++
	}
	return kvs
}

func (m *SafeMap[K, G]) SetKVs(kvs []*KV[K, G]) (err error) {
	m.lock.Lock()
	defer m.lock.Unlock()
	for _, kv := range kvs {
		if kv == nil {
			continue
		}
		m.m[kv.K] = kv.V
	}
	return
}

/**
 * @description: 设置一个map
 * @param {map[K]*G} mp
 * @return {*}
 */
func (m *SafeMap[K, G]) SetMap(mp map[K]*G) (err error) {
	m.lock.Lock()
	defer m.lock.Unlock()
	m.m = mp
	return
}

// 生成指定的map
func (m *SafeMap[K, G]) ToMap(names ...[]K) (mp map[K]*G) {
	m.lock.Lock()
	defer m.lock.Unlock()

	mp = make(map[K]*G)
	if len(names) > 0 {
		for _, name := range names[0] {
			item, ok := mp[name]
			if ok && item != nil {
				mp[name] = item
			}
		}
		return
	}

	for key, val := range m.m {
		mp[key] = val
	}
	return
}
